import random
import sys
import os
import math
from bisect import bisect_left, bisect_right
from collections import Counter, defaultdict, deque
from functools import lru_cache, reduce
from itertools import accumulate, combinations, permutations
from heapq import nsmallest, nlargest, heapify, heappop, heappush
from io import BytesIO, IOBase
from copy import deepcopy
BUFSIZE = 4096
MAX = (1 << 63) - 1
MIN = -MAX
class Segment:
def __init__(self, n):
self.sgm_tree = [0 for i in range(2 * n)]
self.d = {}
def queries(self, l, r):
count = 0
while l <= r:
if l % 2 == 1:
count += self.sgm_tree[l]
l += 1
if r % 2 == 0:
count += self.sgm_tree[r]
r -= 1
l = l >> 1
r = r >> 1
return count
def update(self, indx, num):
if num == 2:
self.d[indx] -= 1
if self.d[indx] == 0:
self.sgm_tree[indx] = 0
else:
if indx not in self.d:
self.d[indx] = 0
self.d[indx] += 1
if self.d[indx] == 1:
self.sgm_tree[indx] = 1
indx = indx >> 1
while indx >= 1:
self.sgm_tree[indx] = self.sgm_tree[2 * indx] + self.sgm_tree[2 * indx + 1]
indx = indx >> 1
class FenwickTree:
def __init__(self, n):
self.n = n
self.bit = [0] * n
def sum(self, r):
res = 0
while r >= 0:
res += self.bit[r]
r = (r & (r + 1)) - 1
return res
def rsum(self, l, r):
return self.sum(r) - self.sum(l - 1)
def add(self, idx, delta):
while idx < self.n:
self.bit[idx] += delta
idx = idx | (idx + 1)
def gcd(a, b):
if a < 0: a = -a
if b < 0: b = -b
if a < b:
a, b = b, a
if a % b == 0:
return b
return gcd(b, a % b)
def toposort(graph):
res, found = [], [0] * len(graph)
stack = list(range(len(graph)))
while stack:
node = stack.pop()
if node < 0:
res.append(~node)
elif not found[node]:
found[node] = 1
stack.append(~node)
stack += graph[node]
for node in res:
if any(found[nei] for nei in graph[node]):
return None
found[node] = 0
return res[::-1]
class FastIO(IOBase):
newlines = 0
def __init__(self, file):
self._fd = file.fileno()
self.buffer = BytesIO()
self.writable = "x" in file.mode or "r" not in file.mode
self.write = self.buffer.write if self.writable else None
def read(self):
while True:
b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
if not b:
break
ptr = self.buffer.tell()
self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
self.newlines = 0
return self.buffer.read()
def readline(self):
while self.newlines == 0:
b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
self.newlines = b.count(b"\n") + (not b)
ptr = self.buffer.tell()
self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
self.newlines -= 1
return self.buffer.readline()
def flush(self):
if self.writable:
os.write(self._fd, self.buffer.getvalue())
self.buffer.truncate(0), self.buffer.seek(0)
class IOWrapper(IOBase):
def __init__(self, file):
self.buffer = FastIO(file)
self.flush = self.buffer.flush
self.writable = self.buffer.writable
self.write = lambda s: self.buffer.write(s.encode("ascii"))
self.read = lambda: self.buffer.read().decode("ascii")
self.readline = lambda: self.buffer.readline().decode("ascii")
sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")
def I():
return input()
def II():
return int(input())
def MI():
return map(int, input().split())
def LI():
return list(input().split())
def LII():
return list(map(int, input().split()))
def TMI(arr):
return list(map(str, arr))
def GMI():
return map(lambda x: int(x) - 1, input().split())
def LGMI():
return list(GMI())
n = II()
h = LII()
dp = [0] * n
stka,stkb = [0],[0]
for i in range(1,n):
dp[i] = dp[i - 1] + 1
while stka and h[stka[-1]] >= h[i]:
tmp = stka.pop()
if h[tmp] > h[i] and stka:
dp[i] = min(dp[i],dp[stka[-1]] + 1)
while stkb and h[stkb[-1]] <= h[i]:
tmp = stkb.pop()
if h[tmp] < h[i] and stkb:
dp[i] = min(dp[i],dp[stkb[-1]] + 1)
stka.append(i)
stkb.append(i)
print(dp[n - 1])
#include <bits/stdc++.h>
#define F first
#define S second
using namespace std;
using ll = long long;
using PI = pair<int, int>;
using PII = pair<PI, int>;
const int N = 3e5+1;
const int INF = 1e9+7;
int ST1[4*N];
int ST2[4*N];
int arr[N];
void build(int l, int r, int v){
if(l == r){
ST1[v] = arr[l];
ST2[v] = arr[l];
return;
}
int mid = (l + r)/2;
build(l, mid, 2*v);
build(mid+1, r, 2*v+1);
ST1[v] = max(ST1[2*v], ST1[2*v+1]);
ST2[v] = min(ST2[2*v], ST2[2*v+1]);
}
int ans = 0;
void query1(int l, int r, int ql, int qr, int k, char c, int v){
if(l == r){
assert(ans == 0);
ans = l;
return;
}
int mid = (l + r)/2;
if(c == 'l'){
if(ST1[2*v+1] >= k && mid+1 <= qr && r >= ql && !ans){
query1(mid+1, r, ql, qr, k, c, 2*v+1);
}
if(ST1[2*v] >= k && l <= qr && mid >= ql && !ans){
query1(l, mid, ql, qr, k, c, 2*v);
}
}
else{
if(ST1[2*v] >= k && l <= qr && mid >= ql && !ans){
query1(l, mid, ql, qr, k, c, 2*v);
}
if(ST1[2*v+1] >= k && mid+1 <= qr && r >= ql && !ans){
query1(mid+1, r, ql, qr, k, c, 2*v+1);
}
}
}
void query2(int l, int r, int ql, int qr, int k, char c, int v){
if(l == r){
assert(ans == 0);
ans = l;
return;
}
int mid = (l + r)/2;
if(c == 'l'){
if(ST2[2*v+1] <= k && mid+1 <= qr && r >= ql && !ans){
query2(mid+1, r, ql, qr, k, c, 2*v+1);
}
if(ST2[2*v] <= k && l <= qr && mid >= ql && !ans){
query2(l, mid, ql, qr, k, c, 2*v);
}
}
else{
if(ST2[2*v] <= k && l <= qr && mid >= ql && !ans){
query2(l, mid, ql, qr, k, c, 2*v);
}
if(ST2[2*v+1] <= k && mid+1 <= qr && r >= ql && !ans){
query2(mid+1, r, ql, qr, k, c, 2*v+1);
}
}
}
int main()
{
ios_base::sync_with_stdio(0); cin.tie(0);
int n; cin >> n;
for(int i = 1; i <= n; i++){
cin >> arr[i];
}
build(1, n, 1);
vector<int> adjl[n+1];
for(int i = 1; i <= n; i++){
int l1 = 0, l2 = 0, r1 = 0, r2 = 0;
if(i == 1){
query2(1, n, i+1, n, arr[i], 'r', 1);
r1 = ans;
ans = 0;
query1(1, n, i+1, n, arr[i], 'r', 1);
r2 = ans;
ans = 0;
}
else if(i == n){
query2(1, n, 1, i-1, arr[i], 'l', 1);
l1 = ans;
ans = 0;
query1(1, n, 1, i-1, arr[i], 'l', 1);
l2 = ans;
ans = 0;
}
else{
query2(1, n, 1, i-1, arr[i], 'l', 1);
l1 = ans;
ans = 0;
query1(1, n, 1, i-1, arr[i], 'l', 1);
l2 = ans;
ans = 0;
query2(1, n, i+1, n, arr[i], 'r', 1);
r1 = ans;
ans = 0;
query1(1, n, i+1, n, arr[i], 'r', 1);
r2 = ans;
ans = 0;
}
if(l1 != 0){
adjl[l1].push_back(i);
}
if(l2 != 0){
adjl[l2].push_back(i);
}
if(r1 != 0){
adjl[i].push_back(r1);
}
if(r2 != 0 ){
adjl[i].push_back(r2);
}
}
queue<int> q;
vector<bool> vis(n+1);
vector<int> dis(n+1);
vis[1] = 1;
q.push(1);
vector<int> parents(n+1);
parents[1] = -1;
while(!q.empty()){
int v = q.front(); q.pop();
for(auto i : adjl[v]){
if(!vis[i]){
vis[i] = 1;
parents[i] = v;
dis[i] = dis[v]+1;
q.push(i);
}
}
}
cout << dis[n];
/*
33
47 864 7 44 132 71 16 3 5 11 132 32 1 132 78 21 8 131 8 1 456 48 4 54 8 13 46 13 156 6 1 1 1
10
1 2 1 1 1 1 1 1 2 1
*/
}
1542A - Odd Set | 1567B - MEXor Mixup |
669A - Little Artem and Presents | 691B - s-palindrome |
851A - Arpa and a research in Mexican wave | 811A - Vladik and Courtesy |
1006B - Polycarp's Practice | 1422A - Fence |
21D - Traveling Graph | 1559B - Mocha and Red and Blue |
1579C - Ticks | 268B - Buttons |
898A - Rounding | 1372B - Omkar and Last Class of Math |
1025D - Recovering BST | 439A - Devu the Singer and Churu the Joker |
1323A - Even Subset Sum Problem | 1095A - Repeating Cipher |
630F - Selection of Personnel | 630K - Indivisibility |
20B - Equation | 600B - Queries about less or equal elements |
1015A - Points in Segments | 1593B - Make it Divisible by 25 |
680C - Bear and Prime 100 | 1300A - Non-zero |
1475E - Advertising Agency | 1345B - Card Constructions |
1077B - Disturbed People | 653A - Bear and Three Balls |